(function() {
    function _validate($input) {
        var input = $input[0]
          , val = $input.val();
          console.log()
        if (input.tagName == "INPUT" || input.tagName == "TEXTAREA") {
            var reg = input.getAttribute("required") || input.getAttribute("pattern") || "";
            if (!$input.val().length) {
                return "empty";
            } else if (reg) {
                return new RegExp(reg).test(val) ? null : "notMatch";
            } else if (input.getAttribute("type") == "checkbox" || input.getAttribute("type") == "radio") {
                var name = input.name,
                    len = $('[name="'+ name +'"]:checked').length; 
                return len ? null : "empty";
            } else {
                return null;
            }
        } else if (val.length) {
            return null;
        }
        return "empty";
    }
    function _showErrorMsg(error) {
        if (error) {
            var $dom = error.$dom
              , msg = error.msg
              , tips = $dom.attr(msg + "Tips") || $dom.attr("tips") || $dom.attr("placeholder");
            if (tips)
                $.toptip(tips);
            $dom.parents(".weui_cell").addClass("weui_cell_warn");
        }
    }
    var oldFnForm = $.fn.form;
    $.fn.form = function() {
        return this.each(function(index, ele) {
            var $form = $(ele);
            $form.find("[required]").on("blur", function() {
                var $this = $(this), errorMsg;
                if ($this.val().length < 1)
                    return;
                errorMsg = _validate($this);
                if (errorMsg) {
                    _showErrorMsg({
                        $dom: $this,
                        msg: errorMsg
                    });
                }
            }).on("focus", function() {
                var $this = $(this);
                $this.parents(".weui_cell").removeClass("weui_cell_warn");
            });
        });
    }
    ;
    $.fn.form.noConflict = function() {
        return oldFnForm;
    }
    ;
    var oldFnValidate = $.fn.validate;
    $.fn.validate = function(callback) {
        return this.each(function() {
            var $requireds = $(this).find("[required]");
            if (typeof callback != "function")
                callback = _showErrorMsg;
            for (var i = 0, len = $requireds.length; i < len; ++i) {
                var $dom = $requireds.eq(i)
                  , errorMsg = _validate($dom)
                  , error = {
                    $dom: $dom,
                    msg: errorMsg
                };
                if (errorMsg) {
                    if (!callback(error))
                        _showErrorMsg(error);
                    return;
                }
            }
            callback(null);
        });
    }
    ;
    $.fn.validate.noConflict = function() {
        return oldFnValidate;
    }
    ;
}
)();